package com.cloudeasy.server.config;

import com.cloudeasy.core.properties.SecurityProperties;
import com.cloudeasy.server.service.CustomUserDetailServiceImpl;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

import javax.servlet.http.HttpServletResponse;

/**
 * 网络安全配置
 */
@Configuration
@EnableWebSecurity
@EnableConfigurationProperties(SecurityProperties.class)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    /**
     * {@link CustomUserDetailServiceImpl}自定义提供的用户详细信息服务
     */
    private final CustomUserDetailServiceImpl customUserDetailServiceImpl;

    public WebSecurityConfig(CustomUserDetailServiceImpl customUserDetailServiceImpl) {
        this.customUserDetailServiceImpl = customUserDetailServiceImpl;
    }

    /**
     * 注册默认的{@link AuthenticationManager}
     *
     * @return {@link AuthenticationManager}
     * @throws Exception 异常
     */
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    /**
     * Http安全配置，关闭CSRF
     * 配置异常处理，授权请求规则，表单登录
     *
     * @param http {@link HttpSecurity}
     * @throws Exception 异常
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .exceptionHandling()
                .authenticationEntryPoint((request, response, authException) -> response.sendError(HttpServletResponse.SC_UNAUTHORIZED))
                .and()
                .authorizeRequests()
                .antMatchers("/oauth/{account:\\S+}/permission","/oauth/{account:\\S+}/role").permitAll()
                .antMatchers("/**").authenticated()
                .and()
                .formLogin();
    }

    /**
     * 验证管理配置
     * 使用{@link CustomUserDetailServiceImpl}自定义提供的用户详细信息服务
     * {@link BCryptPasswordEncoder}密码编码器
     *
     * @param auth {@link AuthenticationManagerBuilder}
     * @throws Exception 异常
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(customUserDetailServiceImpl).passwordEncoder(bCryptPasswordEncoder());
    }

    /**
     * 加密
     *
     * @return {@link BCryptPasswordEncoder}
     */
    @Bean
    public PasswordEncoder bCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }

    /**
     * 认证管理器
     *
     * @return 认证管理器对象
     * @throws Exception 异常
     */
    @Bean
    @Override
    public AuthenticationManager authenticationManager() throws Exception {
        return super.authenticationManager();
    }
}
